package demo.threadpool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * @author Arnold Yand
 * @since Mar 8, 20174:41:12 PM
 * @summary demo.threadpool.ThreadPoolDemo.java
 */
public class ThreadPoolDemo {

    public static void main(String[] args) {
        /**
         * Executors提供四种线程池 ： <br/>
         * newFixedThreadPool 创建一个定长线程池，可控制线程最大并发数。 <br/>
         * newCachedThreadPool 创建一个可缓存线程池，如果线程池长度超过处理需要，可灵活回收空闲线程，若无可回收，则新建线程。<br/>
         * newScheduledThreadPool 创建一个定长线程池，支持定时及周期性任务执行。<br/>
         * newSingleThreadExecutor 创建一个单线程化的线程池，它只会用唯一的工作线程来执行任务，保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。<br/>
         */
        // testFixedThreadPool();
        // testCachedThreadPool();
        testScheduledThreadPool();
        // testSingleThreadPool();
    }

    public static void testSingleThreadPool() {
        ExecutorService executors = Executors.newSingleThreadExecutor();
        for (int i = 0; i < 20; i++) {
            System.out.println("submit tast #" + i);
            executors.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("only one thread to execute all the task, thread name : " + Thread.currentThread().getName());
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                    }
                }
            });
        }

        executors.shutdown();
    }

    public static void testScheduledThreadPool() {
        ScheduledExecutorService scheduledExecutors = Executors.newScheduledThreadPool(5);
        System.out.println("delay 5 seconds to execute the task AAAAA.");
        scheduledExecutors.schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("execute task AAAAA completed.");
            }
        }, 5, TimeUnit.SECONDS);

        System.out.println("delay 3 seconds to execute task BBBBB.");
        scheduledExecutors.scheduleAtFixedRate(new Runnable() {
            @Override
            public void run() {
                System.out.println("execute task BBBBB every 5 seconds.");
            }
        }, 3, 5, TimeUnit.SECONDS);
    }

    public static void testCachedThreadPool() {
        ExecutorService executors = Executors.newCachedThreadPool();
        for (int i = 0; i < 5; i++) {
            System.out.println("submit tast #" + i);
            executors.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("start execute thread :" + Thread.currentThread().getName());
                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                    }
                    System.out.println("execute thread :" + Thread.currentThread().getName() + " completed.");
                }
            });
        }
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e1) {
        }

        System.out.println("回收空闲线程来执行此任务");
        executors.execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("start execute thread :" + Thread.currentThread().getName());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                }
                System.out.println("execute thread :" + Thread.currentThread().getName() + " completed.");
            }
        });

        executors.shutdown();
    }

    public static void testFixedThreadPool() {

        // only 3 threads
        ExecutorService executors = Executors.newFixedThreadPool(3);

        // but submit 20 task to execute
        for (int i = 0; i < 20; i++) {
            System.out.println("submit tast #" + i);
            executors.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("start execute thread :" + Thread.currentThread().getName());
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                    }
                    System.out.println("execute thread :" + Thread.currentThread().getName() + " completed.");
                }
            });
        }

        executors.shutdown();
    }

}
